package com.iccgame.sdk;

import org.sign.*;
import java.net.*;
import java.util.*;

/**
 *
 * @author Administrator
 */
public class SignSerialization {

	public static final String TYPE_MD5 = "md5";
	public static final String TYPE_RSA = "rsa";

	/**
	 * 参数容器
	 */
	protected LinkedHashMap<String, String> _properties = new LinkedHashMap<String, String>();

	/**
	 * 公钥
	 */
	protected String _publicKey = "";

	/**
	 * 私钥
	 */
	protected String _privateKey = "";

	/**
	 * 签名类型
	 */
	protected String _signType = "rsa";

	/**
	 * 签名结果
	 */
	protected String _sign = "";

	/**
	 * 反序列化方法
	 *
	 * @param data
	 * @return
	 */
	public static SignSerialization unserialize(String data) {
		// 实例自己
		SignSerialization that = new SignSerialization();
		// 解析数据
		String[] rows = data.split("&");
		for (int i = 0; i < rows.length; i++) {
			int offset = rows[i].indexOf("=");
			String k = rows[i].substring(0, offset);
			String v = "";
			try {
				v = URLDecoder.decode(rows[i].substring(offset + 1), "UTF-8");
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (k.equals("sign_type")) {
				that._signType = v;
				continue;
			} else if (k.equals("sign")) {
				that._sign = v;
				continue;
			}
			try {
				that.setItem(k, v);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return that;
	}

	/**
	 * 读取一项数据
	 *
	 * @param key
	 * @return
	 */
	public String getItem(String key) {
		return this._properties.get(key);
	}

	/**
	 * 设置一项数据
	 *
	 * @param key
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public SignSerialization setItem(String key, String value) throws Exception {
		if (key.equals("sign") || key.equals("sign_type")) {
			throw new Exception("sign and sign_type not change.");
		}
		this._properties.put(key, value);
		return this;
	}

	/**
	 * 设置公钥
	 *
	 * @param key
	 * @return
	 */
	public SignSerialization setPublicKey(String key) {
		this._publicKey = key;
		return this;
	}

	/**
	 * 设置私钥
	 *
	 * @param key
	 * @return
	 */
	public SignSerialization setPrivateKey(String key) {
		this._privateKey = key;
		return this;
	}

	/**
	 * 验证结果
	 *
	 * @return
	 * @throws Exception
	 */
	public boolean verify() throws Exception {
		String data = this.getSignData();
		String sign = this._sign;
		return this.verify(data, sign);
	}

	/**
	 * 验证结果
	 *
	 * @param sign
	 * @return
	 */
	public boolean verify(String sign) throws Exception {
		String data = this.getSignData();
		return this.verify(data, sign);
	}

	/**
	 * 验证签名
	 *
	 * @param data
	 * @param sign
	 * @return
	 * @throws Exception
	 */
	public boolean verify(String data, String sign) throws Exception {
		if (this._publicKey == null || this._publicKey.isEmpty()) {
			throw new Exception("public key not empty.");
		}
		return RSA.verify(data, sign, this._publicKey, "utf-8");
	}

	/**
	 * 签名数据
	 *
	 * @return
	 * @throws Exception
	 */
	public String sign() throws Exception {
		// 签名数据
		String data = this.getSignData();
		return this.sign(data);
	}

	/**
	 * 签名数据
	 *
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String sign(String data) throws Exception {
		if (this._privateKey == null || this._privateKey.isEmpty()) {
			throw new Exception("private key not empty.");
		}
		// 签名数据
		String sign = RSA.sign(data, this._privateKey, "utf-8");
		return sign;
	}

	/**
	 * 获得签名数据
	 *
	 * @return
	 */
	public String getSignData() {
		StringBuilder buffer = new StringBuilder();
		Iterator iter = this._properties.entrySet().iterator();
		while (iter.hasNext()) {
			if (buffer.length() > 0) {
				buffer.append("&");
			}
			Map.Entry entry = (Map.Entry) iter.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			buffer.append(k);
			buffer.append("=");
			try {
				buffer.append(URLEncoder.encode(v, "UTF-8"));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return buffer.toString();
	}

	/**
	 * 序列化数据
	 *
	 * @return
	 * @throws Exception
	 */
	public String serialize() throws Exception {
		String data = this.getSignData();
		String sign = this.sign(data);
		return data + "&sign_type=rsa&sign=" + URLEncoder.encode(sign);
	}
	// End Class
}
